# -*- coding: utf8 -*-

import os
from subprocess import Popen, PIPE, STDOUT
from archive import BaseAdapter
import math

class MediaInfo(object):

    bin = "/usr/bin/mediainfo"

    filename = None
    proc = None

    def __init__(self, filename, media_info_bin=None):
        self.filename = filename
        if media_info_bin:
            self.bin = media_info_bin
        pass


    def terminate(self):
        if self.proc and self.proc.poll() is None:
            self.proc.terminate()
        return

    def get_info(self, parameter, category="General"):
        # from logger import get_file_logger
        # log = get_file_logger("MediaInfo")

        cmd = [
            self.bin,
            '--Inform=%s;%%%s%%' % (category, parameter,),
            self.filename
        ]

        # log.debug("CMD:\n%r" % (cmd,))

        self.proc = Popen(cmd, stdout=PIPE)
        self.proc.wait()

        output = self.proc.stdout.read()

        # log.debug("Parameter=%r, Category=%r, Filename=%r\nOutput:\n%s" % (parameter, category, self.filename, output,))

        return output.strip()


# mplayer -vo jpeg -sstep 5 file.avi

class MPlayer(object):
    bin = "/usr/bin/mplayer"

    filename = None
    log = None

    def __init__(self, filename, mplayer_bin=None):
        self.filename = filename
        if mplayer_bin:
            self.bin = mplayer_bin
        from logger import get_file_logger

        self.log = get_file_logger("MPlayer")

        pass


    def generate_screenshots(self, duration, size=None, codec="png", every_sec=10):

        cmd = [
            self.bin,
            "-really-quiet",
            "-ao", "null",
            "-vo", codec,
            "-sstep", "%d" % every_sec,
            "-endpos", "%.2f" % (duration - int(every_sec) - 0.5,),
        ]

        if size:
            cmd.append("-vf")
            cmd.append("scale=%s:%s" % (size[0], size[1]))

        cmd.append(self.filename)

        # -vf scale=640:480

        # self.log.debug("Get screenshots CMD: %r" % (cmd,))

        p = Popen(cmd, stdout=PIPE, stderr=STDOUT)
        ret = p.wait()

        if ret != 0:
            self.log.warning("Filename=%r, Stdout:\n%s" % (self.filename, p.stdout.read(),))

        return ret == 0


class Ffmpeg(object):
    bin = "/usr/bin/ffmpeg"

    filename = None
    log = None

    proc = None

    quality = 1.0

    loglevel = "quiet"

    def __init__(self, filename, ffmpeg_bin=None):
        self.filename = filename
        if ffmpeg_bin:
            self.bin = ffmpeg_bin
        from logger import get_file_logger

        self.log = get_file_logger("Ffmpeg")

        pass


    def terminate(self):
        if self.proc and self.proc.poll() is None:
            self.proc.terminate()
        return


    def get_screenshot(self, save_to, size=None, seek_seconds=0.0):

        cmd = [
            self.bin,
            "-loglevel", self.loglevel,
            "-y",
            "-i", self.filename,
            "-ss", "%0.3f" % seek_seconds,
            "-an",
            "-f", "image2",
            "-frames:v", "1",
            "-q:v", "%0.2f" % self.quality,
        ]

        if size:
            cmd.append("-s")
            cmd.append("%sx%s" % (size[0], size[1]))

        cmd.append(save_to)

        # self.log.debug("Get screenshot CMD: %r" % (cmd,))

        self.proc = Popen(cmd, stdout=PIPE, stderr=STDOUT)
        ret = self.proc.wait()

        if ret != 0:
            self.log.warning("Filename=%r, Stdout:\n%s" % (self.filename, self.proc.stdout.read(),))

        return ret == 0


    def generate_screenshots(self, save_pattern, size=None, fps=24.0, every_sec=10):

        cmd = [
            self.bin,
            "-loglevel", self.loglevel,
            "-y",
            "-i", self.filename,
            "-an",
            "-q:v", "%0.2f" % self.quality,
            "-r", "%0.3f" % (1.0 / every_sec,),
            "-threads", "0",
            "-q:v", "%0.2f" % self.quality,
            #            "-vf", "drawtext=fontfile=/usr/share/fonts/truetype/droid/DroidSansMono.ttf:"+
            #                   (" timecode='00\:00\:00\:00': r=%0.2f:" % fps)+
            #                   " x=(w-tw)/2: y=h-(2*lh): fontcolor=white: box=1: boxcolor=0x00000099",
        ]

        if size:
            cmd.append("-s")
            cmd.append("%sx%s" % (size[0], size[1]))

        cmd.append(save_pattern)

        #self.log.debug("Get screenshots CMD: %r" % (cmd,))

        self.proc = Popen(cmd, stdout=PIPE, stderr=STDOUT)
        ret = self.proc.wait()

        if ret != 0:
            self.log.warning("Filename=%r, Stdout:\n%s" % (self.filename, self.proc.stdout.read(),))

        return ret == 0


class VideoArchive(BaseAdapter):
    img_per_sec = 5.0

    proc = None

    pattern = "%d.jpg"

    max_scale_width = 1920
    max_scale_height = 1200

    def terminate(self):
        if self.proc:
            self.proc.terminate()
        return

    def get_files( self ):

        names = []

        self.proc = MediaInfo(self.file_name)

        n_pages = int(float(self.proc.get_info("Duration")) / 1000.0 / self.img_per_sec)

        for i in range(n_pages):
            names.append(self.pattern % i)

        return names


    def extract_files( self, into_dir):

        #if not os.path.isdir(into_dir):
        #    os.makedirs(into_dir)

        # os.chdir(into_dir)

        self.proc = MediaInfo(self.file_name)

        # duration = float(m.get_info("Duration")) / 1000.0

        #n_pages = int( duration / self.img_per_sec )

        width = int(self.proc.get_info("Width", "Video"))
        height = int(self.proc.get_info("Height", "Video"))

        fps = float(self.proc.get_info("FrameRate", "Video"))

        self.proc = None

        #mp = MPlayer( self.file_name )
        #mp.generate_screenshots(duration, (width*2, height*2,), "jpeg", self.img_per_sec)

        self.proc = Ffmpeg(self.file_name)

        if width * height < self.max_scale_width * self.max_scale_height:
            scale = math.sqrt(self.max_scale_width * self.max_scale_height / width * height)
        else:
            scale = 1

        width = int(width * scale)
        height = int(height * scale)
        width -= width % 4
        height -= height % 4

        if width < 2:
            width = 2
        if height < 2:
            height = 2

        page_path = os.path.join(into_dir, self.pattern)
        ret = self.proc.generate_screenshots(page_path, (width, height,), fps, self.img_per_sec)

        self.proc = None
        return ret

        """
        for i in range(n_pages):
            page_path = os.path.join(into_dir, self.pattern % i)
            self.proc.get_screenshot(page_path, "jpg", (width * 2, height * 2,), self.img_per_sec * i)
            # ff.get_screenshot(page_path, "jpg", None, self.img_per_sec*i)

        return
        """
